package com.study.designmodes.service.strategy.component;

import com.study.designmodes.enums.BusinessCodeEnum;
import com.study.designmodes.enums.InsuranceCategoryEnum;
import com.study.designmodes.service.annotation.BusinessTaskAnnotation;
import com.study.designmodes.service.strategy.BusinessTaskHandler;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 注解版-策略bean工厂模式
 * ApplicationContextAware：获取ApplicationContext对象(Spring上下文)
 * Spring容器会在创建该Bean之后，自动调用该Bean的setApplicationContext（参数）方法，调用该方法时，会将容器本身ApplicationContext对象作为参数传递给该方法
 *
 * @author yangyanbin
 * @since 20221106
 **/
@SuppressWarnings("all")
@Component
public class StrategyAnnotationFactory implements InitializingBean, ApplicationContextAware {

    private ApplicationContext applicationContext;

    private static final Map<String, BusinessTaskHandler> VERIFICATION_BUSINESS_SERVICE_MAP = new ConcurrentHashMap<>();


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 获取接口所有的实现类（如果有抽象类实现接口，那么必须要有具体普通的类去继承该抽象类，这样才会获取全部的）
        Map<String, BusinessTaskHandler> taskHandlerMap = applicationContext.getBeansOfType(BusinessTaskHandler.class);
        if (MapUtils.isEmpty(taskHandlerMap)) {
            throw new Exception("业务处理器为空");
        }

        for (Map.Entry<String, BusinessTaskHandler> handlerEntry : taskHandlerMap.entrySet()) {
            BusinessTaskHandler handler = handlerEntry.getValue();
            BusinessTaskAnnotation annotation = AnnotationUtils.findAnnotation(handler.getClass(), BusinessTaskAnnotation.class);
            if (annotation == null) {
                throw new Exception("未获取到注解信息");
            }

            for (InsuranceCategoryEnum categoryEnum : annotation.categoryCode()) {
                for (BusinessCodeEnum businessCodeEnum : annotation.businessCode()) {
                    String key = getKey(categoryEnum, businessCodeEnum);
                    VERIFICATION_BUSINESS_SERVICE_MAP.put(key, handler);
                }
            }

        }

    }

    private static String getKey(InsuranceCategoryEnum categoryEnum, BusinessCodeEnum businessCodeEnum) {
        String categoryCode = categoryEnum == null ? InsuranceCategoryEnum.DEFAULT.getCode() : categoryEnum.getCode();
        String businessCode = businessCodeEnum == null ? BusinessCodeEnum.DEFAULT.getCode() : businessCodeEnum.getCode();
        return categoryCode + "_" + businessCode;
    }


    public static BusinessTaskHandler getBusinessTaskV2Handler(InsuranceCategoryEnum categoryEnum,
                                                               BusinessCodeEnum businessCodeEnum) {
        BusinessTaskHandler businessTaskHandler = VERIFICATION_BUSINESS_SERVICE_MAP.get(getKey(categoryEnum, businessCodeEnum));

        if (Objects.nonNull(businessTaskHandler)) {
            return businessTaskHandler;
        }
    /*    // 如果没有定制，则使用默认业务处理类
        businessTaskHandler = VERIFICATION_BUSINESS_SERVICE_MAP.get(getKey(null, businessCodeEnum));
        if(Objects.nonNull(businessTaskHandler)){
            return businessTaskHandler;
        }

        // 如果没有业务定制，则使用默认处理类
        businessTaskHandler = VERIFICATION_BUSINESS_SERVICE_MAP.get(getKey(null, null));
        if(Objects.nonNull(businessTaskHandler)){
            return businessTaskHandler;
        }*/

        throw new NullPointerException("没找到实现类");

    }


}
